using System;
using System.Collections.Generic;
using System.Net;
using System.IO;
using System.Text.RegularExpressions;
using System.Text;
using System.Threading;

namespace Conusic
{
    public struct Friend
    {
        public Friend(int id, string name, string avataruri, int friendCategoryMask)
            : this()
        {
            Id = id;
            Name = name;
            AvatarUri = avataruri;
            FriendCategoryMask = friendCategoryMask;
        }

        public int Id { get; private set; }
        public string Name { get; private set; }
        public string AvatarUri { get; private set; }
        public int FriendCategoryMask { get; private set; }

        public override string ToString()
        {
            return this.Name;
        }

        public static explicit operator Profile(Friend friend)
        {
            var temp = new Profile(ProfileTypes.Profile, friend.Id.ToString(), friend.Name);
            return temp;
        }
    }

    public static class VkontakteFriends
    {
        private const int MAX_CATEGORY_COUNT = 32;

        public static List<Friend> listFriends { get; private set; }
        public static string[] friendsCategory { get; private set; }

        public static void UpdateFriendsAsync(IFriendsListCommand command)
        {
            ThreadStart threadStart = delegate() { UpdateFriends(command); };
            var thread = new Thread(threadStart);
            thread.Start();
        }

        private static void ParsePageForFriend(string page)
        {
            //                              id     avatar     urlpage    ????      name      category
            var regexpr = new Regex("\\['([^']*)','([^']*)','([^']*)','([^']*)','([^']*)','([^']*)','([^']*)'",
                                    RegexOptions.IgnorePatternWhitespace & RegexOptions.Singleline);

            Match match = regexpr.Match(page);

            while (match.Success)
            {
                int id = int.Parse(match.Groups[1].ToString());
                string name = match.Groups[6].ToString();
                string avatarURI = match.Groups[2].ToString();
                avatarURI = avatarURI.Replace("\\", string.Empty);

                int groups = int.Parse(match.Groups[7].ToString());

                listFriends.Add(new Friend(id, name, avatarURI, groups));

                match = match.NextMatch();
            }
        }

        private static void ParsePageForCategory(string page)
        {
            var regexpr = new Regex(" \" ([0-9]+) \" : \" ([^\"]+) \" ", RegexOptions.IgnorePatternWhitespace);

            Match match = regexpr.Match(page);

            while (match.Success)
            {
                int id = int.Parse(match.Groups[1].ToString());
                string name = match.Groups[2].ToString();

                if (id < MAX_CATEGORY_COUNT)
                    friendsCategory[id] = name;

                match = match.NextMatch();
            }
        }

        private static void ParseFriendsPage(string page)
        {
            ParsePageForFriend(page);
            ParsePageForCategory(page);
        }

        public static List<Friend> UpdateFriends()
        {
            return UpdateFriends(null);
        }

        private static List<Friend> UpdateFriends(IFriendsListCommand command)
        {
            //Wait for Vkontakte access tube
            Config.Instance.VkontakteAccessTube.Wait();

            if (listFriends == null)
            {
                listFriends = new List<Friend>();
            }
            else
            {
                listFriends.Clear();
            }

            try
            {
                var friends = VkontakteApi.RequestApiList<VkApi.FriendsGet.response>("fields=uid,first_name,last_name,photo_big");
                foreach (var user in friends.user)
                {
                    listFriends.Add(new Friend(user.uid, String.Format("{0} {1}", user.first_name, user.last_name), user.photo_big, 0));
                }
            }
            catch (Exception e)
            {
                //todo fix bug expression
                Console.WriteLine(e.ToString());
            }

            if (command != null)
                command.Execute(listFriends);

            return listFriends;
        }
    }
}